package com.ftwj.demo.global.handler;

import javax.validation.ValidationException;

import org.apache.shiro.ShiroException;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.DisabledAccountException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authz.AuthorizationException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.ui.Model;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import com.fasterxml.jackson.core.JsonParseException;
import com.ftwj.demo.base.exception.SQLConverException;
import com.ftwj.demo.utils.StringHelper;
import com.ftwj.demo.utils.exception.CustomException;
import com.ftwj.demo.utils.exception.DataAccessException;
import com.ftwj.demo.utils.exception.JsonException;
import com.ftwj.demo.utils.exception.PageException;
import com.ftwj.demo.utils.exception.ScheduleException;
import com.ftwj.demo.utils.exception.ServerException;
import com.ftwj.demo.utils.exception.ValidateFailedException;
import com.ftwj.demo.utils.result.MessageEnum;
import com.ftwj.demo.utils.result.ResultBean;

/**
 * 
 * @ClassName: CustomControllerAdvice
 * @Description: 统一的异常，参数和模型处理
 * @author: WangShengLi
 * @date: 2019年7月10日 下午7:36:37
 */

@ControllerAdvice
public class CustomControllerAdvice {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(CustomControllerAdvice.class);
	private static final String DEFAULT_ERROR_VIEW = "error";

    @InitBinder
    public void initWebBinder(WebDataBinder binder){

    }

    @ModelAttribute
    public void addAttribute(Model model) {
    	//此处配置全局视图
        model.addAttribute("Global Attribute",  "The Attribute");
    }
    
    @ExceptionHandler(ValidateFailedException.class)
	@ResponseBody
	public ResultBean<?> validateFailedExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,ValidateFailedException {}",e.getMessage());
		return ResultBean.error(MessageEnum.VALIDATE_FILED_ERROR,e.getMessage());
	}
    
    @ExceptionHandler(ValidationException.class)
    @ResponseBody
	public ResultBean<?> validationExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,ValidationException {}",e.getMessage());
		return ResultBean.error(MessageEnum.VALIDATE_FILED_ERROR,e.getMessage());
	}
    
    @ExceptionHandler(MethodArgumentNotValidException.class)
    @ResponseBody
    public ResultBean<?> methodArgumentNotValidExceptionHanlder(Exception e) {
    	String message="参数格式异常";
    	if(StringHelper.isNotEmpty(e.getMessage()) && e.getMessage().indexOf("{")!=-1 && e.getMessage().indexOf("}")!=-1) {
    		message=e.getMessage().substring(e.getMessage().indexOf("{")+1, e.getMessage().indexOf("}"));
    	}
		LOGGER.error("系统异常已捕获,MethodArgumentNotValidException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.MEHOD_AGEUMET_VALIDATE_FILED_ERROR,message);
	}
    
    @ExceptionHandler(DataAccessException.class)
	@ResponseBody
	public ResultBean<?> dataAccessExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,DataAccessException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.DATA_ACCESS_ERROR,e.getMessage());
	}
    
    @ExceptionHandler(SecurityException.class)
   	@ResponseBody
   	public ResultBean<?> securityExceptionHanlder(Exception e) {
   		LOGGER.error("系统异常已捕获,SecurityException {}",e.getMessage());
   	    return ResultBean.error(MessageEnum.SECURITY_ERROR,e.getMessage());
   	}
    
    @ExceptionHandler(UnknownAccountException.class)
    @ResponseBody
    public ResultBean<?> unknownAccountExceptionHanlder(Exception e) {
    	LOGGER.error("系统异常已捕获,UnknownAccountException {}",e.getMessage());
    	return ResultBean.error(MessageEnum.AUTHENTI_UNKNOWN_ERROR);
    }
    
    @ExceptionHandler(LockedAccountException.class)
    @ResponseBody
    public ResultBean<?> lockedAccountExceptionHanlder(Exception e) {
    	LOGGER.error("系统异常已捕获,LockedAccountException {}",e.getMessage());
    	return ResultBean.error(MessageEnum.AUTHENTI_LOCKED_ERROR,e.getMessage());
    }
    
    @ExceptionHandler(DisabledAccountException.class)
    @ResponseBody
    public ResultBean<?> disabledAccountExceptionHanlder(Exception e) {
    	LOGGER.error("系统异常已捕获,DisabledAccountException {}",e.getMessage());
    	return ResultBean.error(MessageEnum.AUTHENTI_DISABLED_ERROR);
    }
    
    @ExceptionHandler(AuthorizationException.class)
    @ResponseBody
    public ResultBean<?> authorizationExceptionHanlder(Exception e) {
    	LOGGER.error("系统异常已捕获,AuthorizationException {}",e.getMessage());
    	return ResultBean.error(MessageEnum.AUTHORI_ERROR);
    }
    
    @ExceptionHandler(AuthenticationException.class)
    @ResponseBody
    public ResultBean<?> authenticationExceptionHanlder(Exception e) {
    	LOGGER.error("系统异常已捕获,AuthenticationException {}",e.getMessage());
    	return ResultBean.error(MessageEnum.AUTHENTI_ERROR);
    }
    
    @ExceptionHandler(ShiroException.class)
    @ResponseBody
    public ResultBean<?> shiroExceptionHanlder(Exception e) {
    	LOGGER.error("系统异常已捕获,ShiroException {}",e.getMessage());
    	return ResultBean.error(MessageEnum.SECURITY_ERROR);
    }
    
    @ExceptionHandler(PageException.class)
	public ModelAndView pageExceptionHanlder(Exception e) {
    	LOGGER.error("系统异常已捕获,PageException {}",e.getMessage());
    	ModelAndView mv=new ModelAndView();
    	mv.addObject("message", e.getMessage());
		mv.setViewName(DEFAULT_ERROR_VIEW);
    	return mv;
    }

	@ExceptionHandler(JsonException.class)
	@ResponseBody
	public ResultBean<?> jsonExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,JsonException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.SERVER_FAILED);
	}
	
	@ExceptionHandler(JsonParseException.class)
	@ResponseBody
	public ResultBean<?> jsonParseExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,JsonParseException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.JSON_PARSE_FILED_ERROR,e.getMessage());
	}
	
	@ExceptionHandler(CustomException.class)
	@ResponseBody
	public ResultBean<?> customExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,CustomException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.CUSTOM_ERROR);
	}
	
	@ExceptionHandler(ScheduleException.class)
	@ResponseBody
	public ResultBean<?> scheduleExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,ScheduleException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.SCHEDULE_ERROR,e.getMessage());
	}
	
	@ExceptionHandler(ServerException.class)
	@ResponseBody
	public ResultBean<?> serverExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,ServerException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.SERVER_ERROR);
	}
	
	@ExceptionHandler(SQLConverException.class)
	@ResponseBody
	public ResultBean<?> sqlConverExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,SQLConverException {}",e.getMessage());
	    return ResultBean.error(MessageEnum.SQL_CONVER_ERROR,e.getMessage());
	}
	
	@ExceptionHandler(RuntimeException.class)
	@ResponseBody
	public ResultBean<?> runtimeExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,RuntimeException {}",e.getMessage());
		LOGGER.error("运行时异常", e);
	    return ResultBean.error(MessageEnum.SERVER_ERROR);
	}
	
	@ExceptionHandler(Exception.class)
	@ResponseBody
	public ResultBean<?> ExceptionHanlder(Exception e) {
		LOGGER.error("系统异常已捕获,Exception {}",e.getMessage());
		LOGGER.error("系统异常", e);
	    return ResultBean.error(MessageEnum.SERVER_ERROR);
	}
	
}
